/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sistemacalidad;

/**
 *
 * @author jorgeorm
 */
public class GeneradorAleatorioStandardMinimo {
    private int semilla, num_tamGrupoNormal;
    private double numeroActual;
    
    /*Variables requeridas para el generador estandard minimo;
     */ 
    
    static int MAX_VALUE = Integer.MAX_VALUE;
    private double factorA, C, modulo, factorQ, factorR;
    
    public GeneradorAleatorioStandardMinimo( int semilla ){
        this.semilla = semilla;
        this.numeroActual = semilla;
        factorA = 16807;
        C = 0;
        modulo = (double) (MAX_VALUE-1);
        factorQ = Math.floor(modulo/factorA);
        factorR = modulo % factorA;
        num_tamGrupoNormal = 12;
    }
    
    /*Devuelve un número pseudo aleatorio entero con distribución uniforme
     */
    public int nextInt(){
        
        obtenerSiguienteNumero();
        
        return (int)numeroActual;
    }
    
    /*calcula el siguiente dato con distribución uniforme
     */
    private void obtenerSiguienteNumero(){
        double calculoParcial = numeroActual % factorQ;
        
        calculoParcial *= factorA;
        
        calculoParcial -= factorR*Math.floor(numeroActual/factorQ);
        
        if(calculoParcial < 0){
            calculoParcial += modulo;
        }
        
        numeroActual = calculoParcial;
    }
    /*Devuelve el siguiente doble con distribución uniforme
     */
    public double nextDouble(){
        
        obtenerSiguienteNumero();
        
        return numeroActual / modulo;
    }
    
    /*Devuelve el siguiente número con distribución normal con média cero y desviación
     * estandar 1
     */
    public double nextGaussian(){
        
        double sumatoria = 0;
        
        SUMATORIA: for( int i=0; i < num_tamGrupoNormal; i++){
            sumatoria += nextDouble();    
        }
        
        if(num_tamGrupoNormal != 12){
            sumatoria -= ((double)num_tamGrupoNormal)/2.0;
            sumatoria /= Math.sqrt(((double)num_tamGrupoNormal)/12.0);
        }else {
            sumatoria -= 6.0;
        }
        
        return sumatoria;
    }
    
}
